package model

import (
	"errors"
	"fmt"
	"gorm.io/gorm"
	"iot-base/auth/utils"
	"time"
)

type (
	AuthRuleModel struct {
		db *gorm.DB
	}
	// AuthRule 权限规则
	AuthRule struct {
		Model
		Type       int    `gorm:"not null" gorm:"comment:1为菜单,2为权限节点" json:"type"`
		Pid        int64  `gorm:"index;default:0" gorm:"comment:父ID" json:"pid"`
		Title      string `gorm:"type:varchar(50)" gorm:"comment:规则标题" json:"title"`
		AuthRule   string `gorm:"index;type:varchar(64);default:''" gorm:"comment: 权限规则" json:"auth_rule"`
		RouterName string `gorm:"type:varchar(64);default:''" gorm:"comment: 前端路由昵称" json:"router_name"`
		Path       string `gorm:"type:varchar(64);default:''" gorm:"comment: 前端的组件路径" json:"path"`
		Method     string `gorm:"type:varchar(64);default:''" gorm:"comment: 请求方法" json:"method"`
		Icon       string `gorm:"type:varchar(64);default:''" gorm:"comment: 菜单图标路径或class名称" json:"icon"`
		Weigh      int    `gorm:"index;default:0" gorm:"comment:权重" json:"weigh"`
		AuthCode   string `gorm:"type:varchar(32)" gorm:"comment:权限编码，用于前端控制按钮/tab标签是否显示" json:"auth_code"`
		Remark     string `gorm:"type:varchar(255);default:''" gorm:"comment:备注字段" json:"remark"`
		Extend     string `gorm:"type:varchar(255);default:''" gorm:"comment:扩展字段" json:"extend"`
		RouterPath string `gorm:"type:varchar(64);default:''" gorm:"comment: 前端路由" json:"router_path"`
		KeepAlive  bool   `gorm:"FORCE" json:"keep_alive"`
	}
)

func NewAuthRuleModel(db *gorm.DB) *AuthRuleModel {
	return &AuthRuleModel{
		db: db,
	}
}

func (m *AuthRuleModel) AddRule(rule *AuthRule) error {
	rule.ID = utils.GetUid()
	rule.CreatedAt = time.Now()
	rule.UpdatedAt = time.Now()
	return m.db.Create(&rule).Error
}

func (m *AuthRuleModel) EditRule(rule AuthRule) error {
	rule.UpdatedAt = time.Now()
	return m.db.Save(rule).Error
}

func (m *AuthRuleModel) DelRule(id int64) error {
	return m.db.Where("id = ?", id).Delete(&AuthRule{}).Error
}

func (m *AuthRuleModel) FindRuleCount(authType int) (int64, error) {
	var count int64
	dbSession := m.db.Model(&AuthRule{})
	if authType != 0 {
		dbSession.Where("type = ?", authType)
	}
	err := dbSession.Count(&count).Error
	if err != nil {
		return count, err
	}
	return count, nil
}

func (m *AuthRuleModel) FindRule(page, size, authType int) ([]AuthRule, error) {
	authRule := make([]AuthRule, 0, 1)
	dbSession := m.db.Limit(size).Offset((page - 1) * size)
	if authType != 0 {
		dbSession.Where("type = ?", authType)
	}
	err := dbSession.Find(&authRule).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return authRule, nil
	} else if err != nil {
		return authRule, err
	}
	return authRule, nil
}

func (m AuthRuleModel) FindRuleAll() ([]AuthRule, error) {
	authRule := make([]AuthRule, 0, 10)
	dbSession := m.db.Limit(1000)
	err := dbSession.Find(&authRule).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return authRule, nil
	} else if err != nil {
		return authRule, err
	}
	return authRule, nil
}

func (m AuthRuleModel) FindRuleByIds(ids []string, ruleType int) ([]AuthRule, error) {
	authRule := make([]AuthRule, 0, 10)
	dbSession := m.db.Where("id in ?", ids)
	err := dbSession.Find(&authRule).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return authRule, nil
	} else if err != nil {
		return authRule, err
	}
	return authRule, nil
}

func (m AuthRuleModel) InitData(authRules []AuthRule) {
	for _, v := range authRules {
		err := m.db.Create(&v).Error
		if err != nil {
			fmt.Println("InitData err:", err)
		}
	}
}
